/*******************************************************************
 * Copyright (c) 2013 珠海比特讯科技有限公司. All rights reserved.
 * （1）软件的版权将受到法律保护，不允许非经授权的使用；
 * （2）未经版权所有人授权，任何人不得修改、复制和传播软件源代码、图片及其它资源等；
 * （3）未经版权所有人授权，不允许对软件进行修改；
 * （4）未经版权所有人授权，不允许在该软件的基础上开发新的软件；
 * （5）珠海比特讯科技有限公司拥有最终解释权
 *******************************************************************/
package youxiao.bytezon.controllers;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.List;
import java.util.Locale;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import youxiao.bytezon.models.CourseDetail;
import youxiao.bytezon.models.Teacher;
import youxiao.bytezon.models.TeacherLessonPremium;
import youxiao.bytezon.repositories.TeacherLessonPremiumRepository;
import youxiao.bytezon.services.TeacherLessonPremiumService;
import youxiao.bytezon.views.commons.PageListView;
import youxiao.bytezon.views.teacher_lesson_premiums.TeacherLessonPremiumSummaryView;
import youxiao.bytezon.views.teacher_lesson_premiums.TeacherLessonPremiumView;

@RestController
@RequestMapping("/teacher_lesson_premiums")
public class TeacherLessonPremiumsController extends BaseController {

	@Autowired
	TeacherLessonPremiumRepository teacherLessonPremiumRepository;
	@Autowired
	TeacherLessonPremiumService teacherLessonPremiumService;
	@Autowired
	EntityManager entityManager;

	@ResponseBody
	@RequestMapping(value = "", method = RequestMethod.GET)
	public PageListView<TeacherLessonPremiumView> index(HttpServletRequest request) {
		String pageNumStr = request.getParameter("page");
		int pageNum = pageNumStr == null ? 0 : Integer.parseInt(pageNumStr) - 1;
		Teacher currentTeacher = getCurrentTeacher();

		Pageable pageable = new PageRequest(pageNum, 50);
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();

		CriteriaQuery<TeacherLessonPremium> cq = cb.createQuery(TeacherLessonPremium.class);
		Root<TeacherLessonPremium> root = cq.from(TeacherLessonPremium.class);
		root.fetch("courseDetail").fetch("course");
		root.fetch("courseDetail").fetch("school");
		
		Join<TeacherLessonPremium, CourseDetail> courseDetailJoin = root.join("courseDetail");
		
		cq.select(root)
			.where(cb.equal(courseDetailJoin.get("teacher"), currentTeacher))
			.orderBy(cb.desc(root.get("billingDate")));
		
		List<TeacherLessonPremium> list = entityManager.createQuery(cq).setFirstResult(pageable.getOffset()).setMaxResults(pageable.getPageSize())
		    .getResultList();

		// query the count of users
		CriteriaQuery<Long> cqCount = cb.createQuery(Long.class);
		Root<TeacherLessonPremium> rootCount = cqCount.from(TeacherLessonPremium.class);
		courseDetailJoin = rootCount.join("courseDetail");
		
		cqCount.select(cb.count(rootCount))
			.where(cb.equal(courseDetailJoin.get("teacher"), currentTeacher));
		
		Long count = entityManager.createQuery(cqCount).getSingleResult();

		Page<TeacherLessonPremium> page = new PageImpl<TeacherLessonPremium>(list, pageable, count);
		return new PageListView<TeacherLessonPremiumView>(page, entry -> new TeacherLessonPremiumView(entry));
	}

	@ResponseBody
	@RequestMapping(value = "/summary", method = RequestMethod.GET)
	public TeacherLessonPremiumSummaryView summary(HttpServletRequest request) {
		TeacherLessonPremiumSummaryView summary = new TeacherLessonPremiumSummaryView();
		Teacher currentTeacher = getCurrentTeacher();

		// Today
		LocalDate today = LocalDate.now();
		BigDecimal todayAmount = teacherLessonPremiumService.getAmountInDay(currentTeacher, today);

		// Yesterday
		LocalDate yesterday = today.minusDays(1);
		BigDecimal yesterdayAmount = teacherLessonPremiumService.getAmountInDay(currentTeacher, yesterday);
		
		// Current week
		TemporalField chinaWeekField = WeekFields.of(Locale.CHINA).dayOfWeek();
		LocalDate currentWeekBeginDate = today.with(chinaWeekField, DayOfWeek.MONDAY.getValue());
		BigDecimal currentWeekAmount = teacherLessonPremiumService.getAmount(currentTeacher, currentWeekBeginDate, today);
		
		// Last week
		LocalDate lastWeekBeginDate = currentWeekBeginDate.minusWeeks(1);
		LocalDate lastWeekEndDate = currentWeekBeginDate.with(chinaWeekField, DayOfWeek.SUNDAY.getValue());
		BigDecimal lastWeekAmount = teacherLessonPremiumService.getAmount(currentTeacher, lastWeekBeginDate, lastWeekEndDate);
		
		// Current month
		LocalDate currentMonthBeginDate = today.with(TemporalAdjusters.firstDayOfMonth());
		BigDecimal currentMonthAmount = teacherLessonPremiumService.getAmount(currentTeacher, currentMonthBeginDate, today);
		
		// Last month
		LocalDate lastMonthBeginDate = currentMonthBeginDate.minusMonths(1);
		LocalDate lastMonthEndDate = lastMonthBeginDate.with(TemporalAdjusters.lastDayOfMonth());
		BigDecimal lastMonthAmount = teacherLessonPremiumService.getAmount(currentTeacher, lastMonthBeginDate, lastMonthEndDate);
		
		summary.setTodayAmount(todayAmount);
		summary.setYesterdayAmount(yesterdayAmount);
		summary.setCurrentWeekAmount(currentWeekAmount);
		summary.setLastWeekAmount(lastWeekAmount);
		summary.setCurrentMonthAmount(currentMonthAmount);
		summary.setLastMonthAmount(lastMonthAmount);
		
		return summary;
	}

	@ResponseBody
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public TeacherLessonPremiumView detail(@PathVariable("id") Long id) {
		TeacherLessonPremium entry = teacherLessonPremiumRepository.findOne(id);
		TeacherLessonPremiumView view = new TeacherLessonPremiumView(entry);
		return view;
	}

}
